import bcrypt from 'bcryptjs';
import { getPool } from '../database/db.js';
import { log } from '../utils/logger.js';

export class User {
  /**
   * 创建新用户
   */
  static async create(username, password, email = null) {
    const pool = getPool();
    try {
      const hashedPassword = await bcrypt.hash(password, 10);
      const [result] = await pool.execute(
        'INSERT INTO users (username, password, email) VALUES (?, ?, ?)',
        [username, hashedPassword, email]
      );
      
      log.system(`新用户注册成功: ${username}`, { userId: result.insertId });
      return result.insertId;
    } catch (error) {
      log.error('用户创建失败', { error: error.message, username });
      throw error;
    }
  }

  /**
   * 根据用户名查找用户
   */
  static async findByUsername(username) {
    const pool = getPool();
    try {
      const [rows] = await pool.execute(
        'SELECT * FROM users WHERE username = ?',
        [username]
      );
      return rows[0] || null;
    } catch (error) {
      log.error('查询用户失败', { error: error.message, username });
      throw error;
    }
  }

  /**
   * 根据ID查找用户
   */
  static async findById(id) {
    const pool = getPool();
    try {
      const [rows] = await pool.execute(
        'SELECT * FROM users WHERE id = ?',
        [id]
      );
      return rows[0] || null;
    } catch (error) {
      log.error('查询用户失败', { error: error.message, userId: id });
      throw error;
    }
  }

  /**
   * 验证密码
   */
  static async verifyPassword(plainPassword, hashedPassword) {
    try {
      return await bcrypt.compare(plainPassword, hashedPassword);
    } catch (error) {
      log.error('密码验证失败', { error: error.message });
      throw error;
    }
  }

  /**
   * 更新用户信息
   */
  static async update(id, updates) {
    const pool = getPool();
    try {
      const allowedFields = ['email', 'password'];
      const fields = [];
      const values = [];

      for (const [key, value] of Object.entries(updates)) {
        if (allowedFields.includes(key)) {
          fields.push(`${key} = ?`);
          values.push(value);
        }
      }

      if (fields.length === 0) {
        return false;
      }

      values.push(id);
      await pool.execute(
        `UPDATE users SET ${fields.join(', ')} WHERE id = ?`,
        values
      );
      
      return true;
    } catch (error) {
      log.error('用户更新失败', { error: error.message, userId: id });
      throw error;
    }
  }

  /**
   * 删除用户
   */
  static async delete(id) {
    const pool = getPool();
    try {
      await pool.execute('DELETE FROM users WHERE id = ?', [id]);
      log.system('用户删除成功', { userId: id });
      return true;
    } catch (error) {
      log.error('用户删除失败', { error: error.message, userId: id });
      throw error;
    }
  }

  /**
   * 更新密码
   */
  static async updatePassword(id, newPassword) {
    const pool = getPool();
    try {
      const hashedPassword = await bcrypt.hash(newPassword, 10);
      await pool.execute(
        'UPDATE users SET password = ? WHERE id = ?',
        [hashedPassword, id]
      );
      log.system('密码更新成功', { userId: id });
      return true;
    } catch (error) {
      log.error('密码更新失败', { error: error.message, userId: id });
      throw error;
    }
  }

  /**
   * 启用TOTP
   */
  static async enableTOTP(id, secret) {
    const pool = getPool();
    try {
      await pool.execute(
        'UPDATE users SET totp_secret = ?, totp_enabled = 1 WHERE id = ?',
        [secret, id]
      );
      log.system('TOTP启用成功', { userId: id });
      return true;
    } catch (error) {
      log.error('TOTP启用失败', { error: error.message, userId: id });
      throw error;
    }
  }

  /**
   * 禁用TOTP
   */
  static async disableTOTP(id) {
    const pool = getPool();
    try {
      await pool.execute(
        'UPDATE users SET totp_secret = NULL, totp_enabled = 0 WHERE id = ?',
        [id]
      );
      log.system('TOTP禁用成功', { userId: id });
      return true;
    } catch (error) {
      log.error('TOTP禁用失败', { error: error.message, userId: id });
      throw error;
    }
  }

  /**
   * 获取所有用户
   */
  static async getAll() {
    const pool = getPool();
    try {
      const [rows] = await pool.execute('SELECT id, username, email, created_at FROM users');
      return rows;
    } catch (error) {
      log.error('获取用户列表失败', { error: error.message });
      throw error;
    }
  }
}
